SignalData

This package should help in organizing and evaluation of large experiments. It uses database resources to store and examine data.

Využití databází pro poloautomatické vyhodnocování velkých objemů dat
Ing. Václav Čejka, VÚTS, a.s., Liberec, vaclav.cejka@vuts.cz

This loads the package:

<<Signals`SignalData`

Functionality is hidden in SignalData command

Working with datasources

Basic manipulation with datasources.

Each set of experiments is supposed to be stored in 1 database. String description of this database is called datasource.

First retrieve the list of all available datasources with signal data:

SignalData[]

Passing the name of the existing datasource opens it, returning connection to the datasource. At this moment also static value is assigned to the symbol, so other uses of the same call does not open database again, but only returns already existing connection.

Open datasource with given name

SignalData["TestDb"]

Connection remains open typically until kernel is closed, but sometimes it might be useful to close the connection manually, especially while open connection limits somehow manipulation with the database. I.e. default HSQL database allows only 1 connection at the time. So the connection can be closed manually with tag "Close"

Manually close the connection

SignalData["TestDb", "Close"]

All other commands can be called passing either datasource name or connection as the first parameter, so following call are identical

SignalData["TestDb",something]

conn=SignalData["TestDb"];
SignalData[conn, something]

Structure of stored data

Experiments

Datasource is the database with specific data structure. It contains experiments described by filename with original data (and internally with unique integer ID). This filename can contains typically relative path to the database files (for HSQL databases), but can contain also absolute path. Max. allowed path length is 250 characters. The path must be unique, because it is used for searching.

Experiement reffers to the whole experiment, not to particular measured data. Different properties can be defined for the experiement, like parameters set on the measured machine, date / time of experiment, location of experiment, temperature etc.

Signals

Signal represents single measured quantity / channel / signal of the experiment. It is uniquelly described by relation to the experiment and property "Quantity" (internally also by unique integer ID). Property "Quantity" is the only property created on default for each SignalData datasource. It is integer number determining uniquelly single measured signal in experiment, i.e. force or acceleration of some specific part of machine. It can be directly channel number from measurement settings or any other well defined enumeration.

Different properties can be again defined for signals, like their mean values, amplitudes of their 1st harmonics, relation to machine part or some manually defined parameter specific for this measurement, that should be used for further processing. Usually only some values are stored to database for some signals, different quantites will have different properties stored. But for the sake of simplicity all signals have the same definition with the same properties.

Signal data

By default the measured signal is not stored to the database, only filename to the experiment. Usually only desired properties are calculated from the original data during import and they are stored to the database. But sometimes even full signals need to be stored. They are typically not full original signals, but i.e. couple of periods from original signal with noise reduced, statistical curves like mean course from multiple cycles, or derived signals, like calculated forces etc. For each signal quantity in 1 experiment 1 signal data can be stored, or better said referenced by database.

Properties

As was mentioned, any number of properties can be defined for experiements and signals. For single datasource, property names for signals and experiments together must be unique to avoid ambiguity in accessing property of experiments and property of signals. Properties has some default attributes and named values can be defined for them.

Attributes

Attributes are predefines basic characteristics of the property. There are definitoric attributes defining the property:

There are also 3 basic descriptive attributes. They can be changed anytime and are used only as i.e. axis labels etc.:

Named values

It might be useful to represent some specific values of some property by user defined description. For example default property "Quantity" is the enumeration of integers, but it would be nice to assign text for it. For some boolean properties interpretation by custom string would be also cute. This is the purpose of named values. Generally any string of 25 characters can be assigned to any combination of property (given by its name), value (given as string of 15 characters) and optionally Quantity (Integer or Null, if assignment is not dependend on Quantity). Value has limit of 15 characters, because obviously it has no meaning of using it on String properties, its is even dangerous, because it cannot be decided, what is true value and what is named value. It should not be used on float values because different possible representations of float values. For boolean properties values "True" and "False" should be used. Value "Null" can be used for any nullable property. Internally all values retrieved from the database will be converted to string using ToString command and then compared. In conditions, string values are supposed to be named values and are searched in database to be translated to their true value.

Named values should be used with care, too many of them may be very slow. Use them only for booleans and enumerations.

There is also a special use of named values together with property units and labels of signals. Many, maybe most signals have different units and labels for different quantities stored in the database. Imagine even basic statistics like mean value, standard deviation, minimum and maximum - they have the same units as original signal, so the attribute "Units" cannot be used directly for all signals of different quantities. Giving string of form "`somestring`" in "Units" and "Label" attributes force the engine to search for named value "somestring" for given property and quantity.

Creating datasources

Of course, new datasource should be created for new set of experiments. It is performed automatically given not yet used datasource name. By default, the option "CreateDataSource" is set to Automatic, which creates new datasource and database files of HSQL database at the current directory. All file names are derived from given datasource name. Other value of "CreateDataSource" option will invoke user interaction dialogs. If database files of HSQL database already exist in current directory, new datasource will just connect to this database.

Create new datasource in current directory using HSQL database

SignalData["NewDatasource"]

Data types

Datasource datatypes.

Althrough database language is largely standardized, still different databases uses little bit different sets of datatypes. List of data types available for particular datasource (its used database) can be recieved by command

SignalData["TestDb","DataType"]

See also DatabaseLink/tutorial/DataTypeMapping.

If you are not sure about specific posibilities of particular datatype, you can ask for its attributes. Here we can see i.e. precision of "DOUBLE" is 17 (for HSQL database on Win32), same as precision of "FLOAT" in this database. But for other databases it might (and usually is) different.

SignalData["TestDb","DataType","DOUBLE"]

SignalData["TestDb","DataType","FLOAT"]

All attributes of all datatypes can be achieved by All tag, like in following example

TableForm[#[[All,2,All,2]],TableHeadings->{#[[All,1]],#[[1,2,All,1]]}]&@SignalData["TestDb","DataType",All]

Configuration

Manipulation with properties.

Typically, datasources are configured with GUI, that can be invoked by command

SignalData["TestDb","GUI"]

It is possible to configure the datasource also manually. Get list of available properties

SignalData["TestDb","Property"]

Add new property of given name and type, and optional decriptive property "Units". Returns the settings of the new property or $Failed

SignalData["TestDb","Property",AddTo,"PropertyName"->"Property1","DataTypeName"->"INTEGER","Units"->"u"]

Property is really added

SignalData["TestDb","Property"]

Now change property name and some descriptive attribute. Function returns number of changed properties, i.e. it should be 1.

SignalData["TestDb","Property",SetAttributes,"PropertyName"->("Property1"->"Property2"),"Units"->"mm"]

Property has changed, let us look at full list of properties and their attributes:

SignalData["TestDb","Property",All]//TableForm

Now change only label

SignalData["TestDb","Property",SetAttributes,"PropertyName"->"Property2","Label"->"Displacement"]

SignalData["TestDb","Property","Property2"]

Property can be also removed (permanently with no possibility of undo!!). More properties can be removed at one, just write them in sequence. Function returns number of removed properties

SignalData["TestDb","Property",Remove,"Property2"]

SignalData["TestDb","Property"]

Conditions (or filters) can be also applied on lists of properties according to their attributes. Let us create some example properties

SignalData["TestDb","Property",AddTo,"PropertyName"->"Property1","DataTypeName"->"INTEGER","Units"->"mm"];
SignalData["TestDb","Property",AddTo,"PropertyName"->"Property2","DataTypeName"->"DOUBLE","Units"->"mm"];
SignalData["TestDb","Property",AddTo,"PropertyName"->"Property3","IsSignalProperty"->False,"DataTypeName"->"INTEGER","Units"->"u"];

List of all signal properties:

SignalData["TestDb","Property",Names,"IsSignalProperty"]

Detailed table of all signal properties of other type than integer:

SignalData["TestDb","Property",All,!StringMatchQ["DataTypeName","INTEGER"]&&"IsSignalProperty"]//TableForm

SignalData["TestDb","Property",All,!StringMatchQ["DataTypename","*INT*"]&&"IssignalProperty"]//TableForm

Detailed table of all signal properties with property being member of some list (stupid example):

SignalData["TestDb","Property",All,MemberQ[{False},"IsSignalProperty"]]//TableForm

In function StringMatchQ only first parameter is treated as attribute name. In function MemberQ only second parameter is treated as attribute name. Any logival expression evaluable by Mathematica can be used as condition, but no other function but StringMatchQ and MemberQ will evaluate strings as attributes names. For example instead of FreeQ use !MemberQ.

Remove properties

SignalData["TestDb","Property",Remove,"Property1","Property2","Property3"]

Adding and updating data in the database

Adding / updating data in the database.

For commiting data to the database, the affected record must be uniquelly identified. There are following possibilities:

For storing new experiment to the database without setting any property or creating any signal only string, typically filename or path to original measured data, must be given. Function returns internal ID identifying the record in the database. Using this ID instead of string in further operations is slightly faster.

Record can be created and new value can be stored all at once. When signal property is stored for some "Quantity", also internal unique ID identifying signal record in the database is returned. When this signal ID is used later in commit, experimenent does not need to be identified again, it is already identified by this signal ID.

For commiting some types of expression, special wrappers must be used, see examples below (SQLDateTime, SQLExpr, SQLBinary).

Each signal can be acompanied by any data stored to external file (in database folder), just commit the expression to "File" property.

First create some properties for experiment and signal

SignalData["TestDb","Property",AddTo,"PropertyName"->"PropertyExp","DataTypeName"->"INTEGER","IsSignalProperty"->False,"Units"->"u"]

SignalData["TestDb","Property",AddTo,"PropertyName"->"PropertySig","DataTypeName"->"INTEGER","IsSignalProperty"->True,"Units"->"u"]

SignalData["TestDb","Property"]

Create new record on experiment, giving its name. Internal ID is returned and can be used later instead of name

SignalData["TestDb","Commit","Experiment"->"a1.uff"]

Properties of this record can be updated anytime later using command like this:

SignalData["TestDb","Commit","Experiment"->"a1.uff","PropertyExp"->1]

Create new record and store some value in one step. Now 2 signal records are stored for single experiment

SignalData["TestDb","Commit","Experiment"->"a3.uff","PropertyExp"->7,"Quantity"->1,"PropertySig"->2]

SignalData["TestDb","Commit","Experiment"->"a3.uff","Quantity"->2,"PropertySig"->9]

"SignalID" can be used to identify record in future. Such a way both signal and experiment record is identified

SignalData["TestDb","Commit","PropertyExp"->8,"SignalID"->("SignalID"/. %),"PropertySig"->3]

There is some special semantics for some type of expressions, see Mathematica documentation. First of all, commiting date and time values must use SQLDateTime wrapper, like in following example

SignalData["TestDb","Property",AddTo,"PropertyName"->"PropertyDate","DataTypeName"->"TIMESTAMP","IsSignalProperty"->False];

SignalData["TestDb","Commit","Experiment"->"a3.uff","PropertyDate"->SQLDateTime[DateList[]]]

Mathematica expressions can be stored to string properties using SQLExpr wrapper, like in following example

SignalData["TestDb","Property",AddTo,"PropertyName"->"PropertyExpr","DataTypeName"->"VARCHAR","DataLength"->50,"IsSignalProperty"->False];

SignalData["TestDb","Commit","Experiment"->"a3.uff","PropertyExpr"->SQLExpr[(x^2)+(y^2)]]

Binary data can be stored to binary properties using SQLBinary wrapper, like in following example

SignalData["TestDb","Property",AddTo,"PropertyName"->"PropertyBinary","DataTypeName"->"VARBINARY","IsSignalProperty"->False]

SignalData["TestDb","Commit","Experiment"->"a3.uff","PropertyBinary"->SQLBinary[ToCharacterCode[ExportString[Plot[Sin[x],{x,0,2 Pi}], "GIF"]]]]

SignalData["TestDb","Property",Remove,"PropertyDate","PropertyExpr","PropertyBinary"]

Each signal can be acompanied by any data stored to external file (in database folder), just commit the expression to "File" property.

SignalData["TestDb","Commit","Experiment"->"a3.uff","Quantity"->1,"File"->Range[100]]

Extracting data from the database

Basic possible ways of data extraction.

Extracting experiment data in raw form

Ways of extraction of experiment data.

Experiments can be filtered based on some condition. Conditions typically contain property names, comparisons and logical operand. Operand MemberQ and string matching StringMatchQ are also supported. Condition is held (using Hold) not to be evaluated outside of database engine. If you need to evaluate some part of condition before database engine is launched, you can surrond it by Evaluate.

Property "File" returns path to the file associated with given signal. It is stored with simple Compress[expr] command, but we do not recommend loading it manually because of possible future change in implementation. Instead use procedure described below.

Options for extracting experiment data.

"SortingColumns" can be

"ShowColumns" can be either list of property names or string containg comma delimited list of property names. Default value "*" gives all properties in the datasource.

There is also little hack possible on "ShowColumns" property. It is directly used in SQL Select command, so also any syntax that the database can undestand can be used. For example there might by value "Property1 + 2 * Property2 AS ArtificialProperty" gives property called "ArtificialProperty" composed from algebraic combination of original properties. But use this hack with care, there is no check for validity of string.

There are 2 possible values of "ResultType" option at this moment. Default option Rule translates table recieved from the database to list of rules, see below. Option Table gives directly table of results recieved from the database.

See all experiment names in the database

SignalData["TestDb","Experiment"]

We can see all experiments with all their properties

SignalData["TestDb","Experiment",All]//TableForm

Now only properties of 1 experiment, together with properties of its signals

SignalData["TestDb","Experiment","a3.uff"]

SignalData["TestDb","Experiment",2]

Experiments can be also filtered based on some condition. See list of experiments filteres for some value of experiment property. Some experiments in the result have no signals, but experiment is listed, because they hold the condition. Other experiment may have more signals and all signals are listed, because all of them “satisfy” restriction put on experiment.

SignalData["TestDb","Experiment","PROPERTYEXP">3]//TableForm

On the contrary restriction put on some signal property show only some signals of some experiments, not all signals of experiment for which restriction is passed.

SignalData["TestDb","Experiment","PROPERTYSig"<=3]//TableForm

Conditions can be even more complex, see following examples

SignalData["TestDb","Experiment","PROPERTYSig"+"PropertyExp">10]//TableForm

SignalData["TestDb","Experiment","FILE"==Null]//TableForm

SignalData["TestDb","Experiment",!MemberQ[{3,4},"PROPERTYSIG"]]//TableForm

Properties can be sorted and also only some properties can be shown in the result:

SignalData["TestDb","Experiment","QUANTITY"==2, "ShowColumns"->"QUANTITY", "SortingColumns"->{"QUANTITY - PROPERTYSIG"->"Descending"}]//TableForm

SignalData["TestDb","Experiment","PROPERTYEXP">3, "SortingColumns"->"QUANTITY"]//TableForm

Especially when condition are generated by some code, you might need to evaluate some part of condition. Sometimes Mathematica evaluates is automatically, sometimes not, I do not understand.

With[{a=1},SignalData["TestDb","Experiment","PROPERTYEXP">Evaluate[a+2]]//TableForm]

Extracting combined data

More advanced way of extracting data is direct composition of stored information to computable data, or otherword direct analysis of dependences between properties. Basic example would be

a=SignalData["TestDb","PROPERTYSIG","PROPERTYEXP","Quantity"==1]

ListLinePlot[a]

This is equivalent to call

SignalData["TestDb","Experiment","Quantity"==1, "ShowColumns"->"PROPERTYEXP, PROPERTYSIG","SortingColumns"->"PropertyExp"]//TableForm

But obviously the first call is shorter. How does it work? First parameter is property (or list of properties) that should be used as dependent variable (y-values), second parameter gives property used for independent variable (x-values). Condition at the end is the same. Data extracted from the database are sorted by independent variable. If both dependent and independent variable are numeric, data are returned as signal (evenly or unevenly sampled), otherwise list of pairs {x,y} is returned.

There is special case of "File" signal property. In this case file is loaded and function returns list of pairs of form {xvalue, loaded file}.

Database functions can be used in demanded columns, but be aware of using only such functions supported by chosen database. Mathematica performs no check on validity of results, also signal labels and units are invalid.

Demanded x- and y-values does not need to be exactly original properties, some calculations can be performed on them by the database

SignalData["TestDb","2 * PROPERTYSIG * PROPERTYEXP","3*PROPERTYEXP","Quantity"==1]

Database functions can be used in demanded columns, but be aware of using only such functions supported by chosen database. Mathematica performs no check on validity of results, also signal labels and units are invalid.

You can also extract data in form of some Mathematica expression with variables denoted as property names. Such call can consist of any Mathematica expression in place of y-variables, all  strings are extracted and used as property names or database expressions. It means if you use any string not related do the database and properties inside the expression, function will fail. Independent variable must still be string representing property or database expression. There is again no check on validity, so unpredictable results can occur if misused.

Database aggreagtion functions can be used in x and y columns with some restrictions:

If aggregation function is used for x column (property), the there is only 1 x-axis point in the result (or none). If aggregation function is used for some y column but not for x column, x column will be used for grouping results, so aggregation  functions on y columns will be applied on sets of values for which x is the same. For example is x is "Quantity" and y is Avg(Prop1), average value separately for each quantity is calculated.

You can use "NoSignal" option set to True to force package to generate list results even for numeric data.

You can make contingention tables by providing list of x-properties. In this case data will be extracted with x-axis of the first property in the list multiple times for each value of other properties present in the database.

The same result as above, but calculation is performed by Mathematica on data recieved from the database

SignalData["TestDb",2 * "PROPERTYSIG" *"PROPERTYEXP","3*PROPERTYEXP","Quantity"==1]

SignalData["TestDb","Property"]

There is an example of extracting stored file. Property name is "File", all stored files are read in order given by "PropertyExp". The result is list of contents of all stored files.

SignalData["TestDb","File","PropertyExp","File"≠Null]

SignalData["TestDb","FileName","PropertyExp","File"≠Null]

Filename of stored experiment can be also used in conditions.

SignalData["TestDb","File","PropertyExp","FileName"=="a1.uff"]

You can use database aggregation functions to calculate some basic statistics on stored results, i.e. number of stored signals (but not experiments, signals are always added to query!)

SignalData["TestDb","Count(Quantity)",""]

Be careful, if you count some experiment property, it will be counted even for experiments with no signal defined.

SignalData["TestDb","Count(PropertyExp)",""]

You can calculate number of signals for particular quantities. Option "NoSignal" forces package to generate list instead of Signal object for numeric result

SignalData["TestDb","Count(PropertyExp)","Quantity","Quantity"≠Null,"NoSignal"->True]

You can make contingation table providing more properties for x-values. In this case, data of PropertySig are extracted based on PropertyExp for each value of Quantity.

SignalData["TestDb","PropertySig",{"PropertyExp","Quantity"},True,"NoSignal"->True]

If you wish to mark each file somehow, you might want to load also another property as marking property

a=SignalData["TestDb",{"PropertySig","File"},"PropertyExp","File"≠Null]

In this case you can combine marks with stored data i.e. this way:

Transpose@{YValues[a[[1]]],a[[2]]}

YValues function could be applied during extraction of data:

Transpose@SignalData["TestDb",{YValues@"PropertySig","File"},"PropertyExp","File"≠Null]

Particularly working with files, but it is also possible in any other case, independent variable can be undefined by providing empty string. In this case dependent values are always returned as a list, no try to convert them to signal

Transpose@SignalData["TestDb",{"PropertySig","File"},"","File"≠Null]

You can perform Mathematica expressions on data from files

SignalData["TestDb",2*"File","PropertyExp","File"≠Null]

But be aware of combining file data with other properties. Data are first read from the database and than combined. It means, that like in following example, Signalis created from "PropertySig", actually consisting of single value. File is loaded for each record fitting the condition, in this case it is only 1 file representing list of numbers. Then this signal and list is multiplied, giving very unsatisfactory results. In case of more records fitting the condition the result will be even more strange.

SignalData["TestDb","File"*"PropertySig","PropertyExp","File"≠Null]

SignalData["TestDb","Property",Remove,"PropertyExp","PropertySig"]

Deleting data from the database

Deleting data from the database.

There are 2 basic possibilities of deleting from the database - either only signal are deleted and experiments are hold, or both signals and experiments are deleted. When signal is deleted, also the stored datafile joined to the signal is deleted.

The same types of conditions used for extracting of the raw data from the databse can be used. When no condition is provided, it is evaluated as All. Of course, for deleting signal condition based on experiment properties can be also used, but when there is no condition specific to any signal, all signals from fintered experiments will be deleted - but experiments will remain in the database.

Experiment can be deleted only if all of its signals are deleted - either by deleting signal separately or by providing such condition that all signals are deleted together with the experiment. If some experiment could not be deleted, it remains in the database (but possibly some of its signals are deleted) and only empty experiments are deleted.

All signals with quantity=1 from all experiments are deleted.

SignalData[dbname,"DeleteSignal","Quantity"==1]

Named values

Named values do not need to be managed manually, you can use graphical user interface

SignalData[datasource,"GUI"]

Adding and removing

Basic constructs for manipulation with named values.

For simplification of manipulation with data, certain combination of property (given by its name), value (given as string of 15 characters) and optionally Quantity (Integer or Null, if assignment is not dependend on Quantity) can be represented by user-defined string.

First of all, named values should be used for naming Quantities

SignalData["TestDb","NamedValue",AddTo,"Quantity"==1->"Force"]

Adding (or updating) new named value uses notation in form (condition)->value. There are some restrictions on conditions: only equality conditions are allowed and only one property column optionally with Quantity can be used. On the contrary, more named values can be added at the same time

Create property and define more named values at once

SignalData["TestDb","Property",AddTo,"PropertyName"->"BooleanProperty","DataTypeName"->"BOOLEAN","IsSignalProperty"->True]

SignalData["TestDb","NamedValue",AddTo,("BooleanProperty"==True&&"Quantity"==1)->"It's true!",("BooleanProperty"==False&&"Quantity"==1)->"It's false!",("BooleanProperty"==Null&&"Quantity"==1)->"It's not defined!"]

Also any boolean functions can be used to define more values at once, althrough this is not recommended - in this case 2 different values of some property have the same named value, i.e. it is impossible to recognize them in conditions, first of them will be used and probably unexpected behaviour can occur

Not recommended, but possible way also

SignalData["TestDb","NamedValue",AddTo,(("BooleanProperty"==True||"BooleanProperty"==False)&&"Quantity"==1)->"Defined",("BooleanProperty"==Null&&"Quantity"==1)->"Undefined"]

Given the same condition but no rule, Remove tag can be used to remove undesired named value (ambigous)

SignalData["TestDb","NamedValue",Remove,("BooleanProperty"==True&&"Quantity"==1)]

When the property is removed, also all its named values are removed. If you perform this command, create property and named values again to enable furter examples

SignalData["TestDb","Property",Remove,"BooleanProperty"]

SignalData["TestDb","NamedValue",All]//TableForm

Viewing

Possible ways of analyzing named values.

Each named value is defined by property for which is used, property value (translated to string) and optionally quantity value for which the named value is used only. These informations are stored in list of 4 elements. Property in the first column, original value in th 2nd column, possible bounding with quantity (in numeric representation) in th 3rd column, and finally named valued.

Condition can contain Equal, And, Or and MemberQ logical functions. Not and other functions are not supported.

Table of all defined named values and their conditions

SignalData["TestDb","NamedValue",All]//TableForm

List of all properties, for which some named value is defined:

SignalData["TestDb","NamedValue"]

Giving only property name, all named values assigned to this property are returned

SignalData["TestDb","NamedValue", "BooleanProperty"]

Or you may ask for all named values for given condition

SignalData["TestDb","NamedValue","QUANTITY"==1]

Quantity alone is the named value, so it can be used in query

SignalData["TestDb","NamedValue","QUANTITY"=="Force"]

See another examples of querying named values

SignalData["TestDb","NamedValue","BOOLEANPROPERTY"==Null]

SignalData["TestDb","NamedValue","BOOLEANPROPERTY"=="Undefined"]

SignalData["TestDb","NamedValue","BOOLEANPROPERTY"=="Defined"&&"QUANTITY"=="Force"]

SignalData["TestDb","NamedValue","BOOLEANPROPERTY"=="Defined"]

Using filters on named values has one important issue. The SignalData function has attribute HoldRest to avoid evaluation of conditions before passing them to the function. Such a way it is not possible to use anything, that should be evaluated before calling the function.

Example of simple construction that does not work:

a={{"BOOLEANPROPERTY", "Undefined"},{"Quantity",1}};SignalData["TestDb","NamedValue",a[[1,1]]==a[[1,2]]&&a[[2,1]]==a[[2,2]]]

Valid result is returned if condition is passed explicitly

SignalData["TestDb","NamedValue","BOOLEANPROPERTY"=="Undefined"&&"Quantity"==1]

This behaviour is a big obstacle in using SignalData in some other function using variable conditions. There is a syntax of SignalData command to be used. This syntax assembles the condition for itself, passing only array of pairs of property and filtered value

SignalData["TestDb","NamedValue",Compose,a]

Interesting behaviour of Mathematica is, that some expression are evaluated, I do not understand it:

a={"BOOLEANPROPERTY", "Undefined"};SignalData["TestDb","NamedValue",First[a]==Last[a]]

Quantities

There are some special functions for working with named values for default "Quantity" property. They are used internally, but use it with care

Analyzing quantities.

You can ask for numeric value of some Quantity string

SignalData["TestDb","QUANTITY","Force"]

Using in data manipulation

Main purpose of named values is better formulation of data extraction (and commit). In conditions, named values are accepted only in equalities, unequalities and MemberQ function, not in comparison and other functions.

Main purpose of named values is better formulation of data extraction (and commit). Use named value in query used above

SignalData["TestDb","PROPERTYSIG","PROPERTYEXP","Quantity"=="Force"]

Let us commit the boolean property based on named values

SignalData["TestDb","Commit","Experiment"->"a3.uff","BooleanProperty"->"Defined","Quantity"->"Force"]

Now extract signal based on filter with named values

SignalData["TestDb","PROPERTYSIG","PROPERTYEXP",("BOOLEANPROPERTY"=="Defined")&&("Quantity"=="Force")]

Named values are also applied to recieved data. If you want to avoid it, you must use “Experiment” tag, see above.

SignalData["TestDb","BOOLEANPROPERTY","PROPERTYEXP"]

SignalData["TestDb","PROPERTYEXP","BOOLEANPROPERTY"]

Label and units

Named values in form “`somestring`” can be used as Label and Units attribute of any property. In this case  named value somestring is searched for given property and quantity and used as label / unit of the output. If Quantity is not unique, the string somestring is used.

Prepare some properties and named values for their descriptive attributes

SignalData["TestDb","Property",SetAttributes,"PropertyName"->"PropertySig","Label"->"`sigLabel`","Units"->"`sigUnits`"];

SignalData["TestDb","NamedValue",AddTo,("PropertySig"=="sigLabel"&&"Quantity"=="Force")->"Force"];

SignalData["TestDb","NamedValue",AddTo,("PropertySig"=="sigUnits"&&"Quantity"=="Force")->"N"];

SignalData["TestDb","NamedValue",AddTo,("PropertySig"=="sigLabel"&&"Quantity"==2)->"Displacement"];

SignalData["TestDb","NamedValue",AddTo,("PropertySig"=="sigUnits"&&"Quantity"==2)->"mm"];

Now signals created from database from different quantities have different labels and units of PropertySig.

SignalData["TestDb","PROPERTYSIG","PROPERTYEXP","Quantity"=="Force"]

SignalData["TestDb","PROPERTYSIG","PROPERTYEXP","Quantity"==2]

If quantity in resulting signal is not unique, labels and units based on named values are not defined. But this situation is more the fault of the user.

SignalData["TestDb","PROPERTYSIG","PROPERTYEXP","PropertySig"≠Null]